﻿/*
 * TextReader.h
 */

#ifndef __GDK_TEXTREADER_H__
#define __GDK_TEXTREADER_H__


#include <gdk/core/Types.h>
#include <gdk/core/Stream.h>



namespace gdk
{



	class GDK_CORE_EXPORT TextReader
	{

		class IReader : public Unknown
		{
			DECLARE_CLASS_HANDLE(IReader)

		private:
			Input::Handle _i;

		protected:
			__INLINE__ IReader(Input *i)
				: _i(i)
			{}

		public:
			__INLINE__ Input* getInput(void) const { return _i; }
			__INLINE__ ssize_t available(void) const { return (!_i.isNull() ? _i->available() : -1); }

			virtual int getch(void) = 0;
		};

		class AnsiReader : public TextReader::IReader
		{
			DECLARE_CLASS_HANDLE(AnsiReader)
			DECLARE_CLASS_INSTANCE1(AnsiReader, Input*);


		public:
			__INLINE__ AnsiReader(Input *i)
				: IReader(i)
			{}

			virtual int getch(void);
		};

		class WideReader : public TextReader::IReader
		{
			DECLARE_CLASS_HANDLE(WideReader)
			DECLARE_CLASS_INSTANCE1(WideReader, Input*);

		public:
			__INLINE__ WideReader(Input *i)
				: IReader(i)
			{}

			virtual int getch(void);
		};

		class Utf8Reader : public TextReader::IReader
		{
			DECLARE_CLASS_HANDLE(Utf8Reader)
			DECLARE_CLASS_INSTANCE1(Utf8Reader, Input*);

		public:
			__INLINE__ Utf8Reader(Input *i)
				: IReader(i)
			{}

			virtual int getch(void);
		};


	public:
		enum CharacterSet
		{
			enumUtf8,
			enumWide,
			enumAnsi,
		};

	private:
		IReader::Handle	_reader;


	public:
		__INLINE__ TextReader(void)
		{
		}
		__INLINE__ TextReader(Input *i, CharacterSet characterSet = enumUtf8)
		{
			open(i, characterSet);
		}

		bool open(Input *i, CharacterSet characterSet = enumUtf8);
		__INLINE__ void close(void)
		{
			_reader = NULL;
		}


#ifdef TEXTWRITER_READ
#undef TEXTWRITER_READ
#endif
#define TEXTWRITER_READ(String) \
		bool read(String &text)\
		{\
			if (_reader == NULL) return false;\
\
			String::TyChar psz[8192 + 8];\
			ssize_t idx = 0;\
			psz[0] = 0;\
\
			text = NULL;\
			while (_reader->available() > 0)\
			{\
				int ch = _reader->getch();\
				if (ch == -1) break;\
\
				idx += charToString(psz + idx, ch);\
				if (idx >= 8192)\
				{\
					text += psz;\
					psz[0] = 0;\
					idx = 0;\
				}\
			}\
			text += psz;\
\
			return true;\
		}\
		bool readLine(String &text)\
		{\
			if (_reader == NULL || _reader->available() <= 0) return false;\
\
			String::TyChar psz[8192 + 8];\
			ssize_t idx = 0;\
			psz[0] = 0;\
\
			text = NULL;\
			while (_reader->available() > 0)\
			{\
				int ch = _reader->getch();\
				if (ch == -1) break;\
				if (ch == '\n') break;\
				if (ch == '\r') continue;\
\
				idx += charToString(psz + idx, ch);\
				if (idx >= 8192)\
				{\
					text += psz;\
					psz[0] = 0;\
					idx = 0;\
				}\
			}\
			text += psz;\
\
			return true;\
		}

		TEXTWRITER_READ(StringAnsi);
		TEXTWRITER_READ(StringWide);
		TEXTWRITER_READ(StringUtf8);

	};




}//namespace gdk


#endif //__GDK_TEXTREADER_H__
